﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System.IO;

namespace SynchronizedPlayer {
	class Playlist : List<PlaylistItem> {
		private static MD5 hashAlgo = MD5.Create();

		public void add(string[] paths) {
			foreach (string path in paths) {
				add(path);
			}
		}

		public void add(string path) {
			Add(new PlaylistItem(getHash(path), getFilename(path), path));
		}

		public void remove(int index) {
			Remove(this[index]);
		}

		private static string getHash(string path) {
			long fileSize = new FileInfo(path).Length;
			string toHash = getFilename(path) + fileSize;
			byte[] s = Encoding.UTF8.GetBytes(toHash);
			byte[] hash = hashAlgo.ComputeHash(s, 0, s.Length);
			string base64hash = Convert.ToBase64String(hash);
			return base64hash;
		}

		private static string getFilename(string path) {
			return path.Split('\\').ToList().Last();
		}

		public static Playlist create(string[] hashesReceived) {
			Dictionary<string, string> hashes = new Dictionary<string, string>();
			string[] paths = Directory.GetFiles("C:\\Music"); // TODO
			foreach (string path in paths) {
				hashes.Add(getHash(path), path);
			}

			Playlist playlist = new Playlist();
			foreach (string hash in hashesReceived) {
				if (hashes.ContainsKey(hash)) {
					playlist.add(hashes[hash]);
				}
			}

			return playlist;
		}

		public string getPath(string filename) {
			foreach (PlaylistItem item in this) {
				if (item.displayName == filename) {
					return item.path;
				}
			}

			return string.Empty;
		}

		public string[] getHashes() {
			string[] hashes = new string[Count];
			for (int i = 0; i < hashes.Length; i++) {
				hashes[i] = this[i].hash;
			}
			return hashes;
		}
	}

	class PlaylistItem {
		public PlaylistItem(string hash, string displayName, string path) {
			this.hash = hash;
			this.displayName = displayName;
			this.path = path;
		}

		public string hash { get; set; }
		public string displayName { get; set; }
		public string path { get; set; }

		public override string ToString() {
			return displayName;
		}
	}
}
